#include "QiliSubtitles.h"

#include "QiliSubtitleAvatar.h"
#include "QiliSubtitleText.h"
#include "QiliSubtitleEmoji.h"
#include "QiliTitleBar.h"

#include "Utility.h"

#include <QVBoxLayout>
#include <QGraphicsItemGroup>
#include <QScrollBar>
#include <QJsonObject>

class QiliSubtitleBlock : public QGraphicsItemGroup
{
public:
    static constexpr qreal HGAP = 0.2;
    static constexpr qreal VGAP = 0.8;
    static constexpr qreal MARGIN = 7;

    QiliSubtitleBlock(const QString &username, const QString &avatar, const QString &text, QGraphicsItem *parent = nullptr)
        : QGraphicsItemGroup(parent)
    {
        qreal gap = HGAP;
        qreal xOffset = MARGIN;
        qreal yOffset = MARGIN;

        mAvatar = new QiliSubtitleAvatar(avatar);
        mAvatar->setPos(xOffset, xOffset);

        xOffset += QiliSubtitleAvatar::WIDTH;
        xOffset += gap;

        mUsername = new QiliSubtitleText(username);
        auto font = mUsername->font();
        font.setBold(true);
        mUsername->setFont(font);
        mUsername->setPos(xOffset, yOffset);

        xOffset += mUsername->boundingRect().width();
        xOffset += gap;

        mText = new QiliSubtitleText();
        mText->setHtml(text);
        mText->setPos(xOffset, yOffset);

        addToGroup(mAvatar);
        addToGroup(mUsername);
        addToGroup(mText);
    }

    // ~QiliSubtitleBlock()
    // {
    //     delete mAvatar;
    //     delete mUsername;
    //     delete mText;
    // }

private:
    QiliSubtitleAvatar *mAvatar;
    QiliSubtitleText   *mUsername;
    QiliSubtitleText   *mText;
};

QiliSubtitles::QiliSubtitles(QWidget *parent)
    : QiliDialog(parent)
{
    setFixedSize(500, 200);
    auto *titleBar = new QiliTitleBar(this);
    titleBar->setText(tr("Subtitles"));
    QObject::connect(titleBar, &QiliTitleBar::closing, this, &QiliSubtitles::close);

    // setContentsMargins(0, 0, 0, 0);
    mScene = new QGraphicsScene(this);
    // mScene->setSceneRect(0, 0, 290, 490);

    mView = new QGraphicsView(this);
    mView->setRenderHint(QPainter::Antialiasing, true);
    mView->setInteractive(true);
    mView->setScene(mScene);
    mView->setContentsMargins(0, 0, 0, 0);
    // mView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    mView->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
    mView->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);

    auto *layout = new QVBoxLayout(this);

    layout->setContentsMargins(0, 0, 0, 0);
    layout->setSpacing(0);

    layout->addWidget(titleBar, 0);
    layout->addWidget(mView, 1);

    adjustSize();
    mOffset = 0;
    mHeight = 0;
}

void QiliSubtitles::subtitleReceived(const QString &username, const QString &avatar, const QString &subtitle, const QJsonObject &emots)
{
    using namespace Utility::JSON;
    QString emojiSubtitle = subtitle;
    for (const auto &key : emots.keys()) {
        auto emot = emots[key] >> JObject;
        auto url = emot / "url" >> JString;
        url = QiliSubtitleEmoji::load(url);
        emojiSubtitle.replace(key, QString("<img src=\"%1\" display=\"inline\" width=\"15\" height=\"15\" align=\"bottom\"/>").arg(url));
    }
    buildBlock(username, avatar, emojiSubtitle);
}

void QiliSubtitles::likeClicked(const QString &username, const QString &avatar, const QString &words)
{
    buildBlock(username, avatar, words);
}

void QiliSubtitles::userEntered(const QString &username, const QString &avatar, const QString &welcome)
{
    buildBlock(username, avatar, welcome);
}

void QiliSubtitles::buildBlock(const QString &username, const QString &avatar, const QString &text)
{
    auto *block = new QiliSubtitleBlock(username, avatar, text);
    block->setPos(0, mOffset);
    mOffset += QiliSubtitleBlock::VGAP; // Gaps between each block
    qDebug() << "Block boundingRect = " << block->boundingRect();
    mOffset += block->boundingRect().height();
    mScene->addItem(block);
    auto viewSize = mView->size().toSizeF();
    auto height = qMax(mOffset + QiliSubtitleBlock::MARGIN, viewSize.height() - 2);
    mScene->setSceneRect(0, 0, viewSize.width(), height);
    auto *scrollBar = mView->verticalScrollBar();
    scrollBar->setValue(scrollBar->maximum());
    // mView->shear(0, 0);
}
